package com.sz.netty.util;

import com.sz.netty.entity.DtuFtpInfo;
import com.sz.netty.entity.DtuFtpMessageDetail;
import com.sz.netty.entity.DtuTransportInfo;
import com.sz.netty.transport.TransportContext;
import com.sz.netty.transport.TransportPoint;
import com.sz.netty.transport.VibrationRecord;
import com.sz.netty.transport.RadarRecord;
import lombok.extern.slf4j.Slf4j;

import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Queue;
import java.util.Set;

/**
 * Utility class for logging transport events to the selog directory
 */
@Slf4j
public class TransportEventLogger {
    
    private static final String LOG_BASE_DIR = "netty-log/selog";
    private static final SimpleDateFormat TIMESTAMP_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private static final SimpleDateFormat FILENAME_FORMAT = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss-SSS");
    
    /**
     * Log start point detection event
     * 
     * @param deviceId Device ID
     * @param messageDetail Message detail that triggered the start point
     * @param deviceInfo Device configuration parameters
     * @param transportTimes Current transport times for the day
     */
    public static void logStartPointEvent(String deviceId, DtuFtpMessageDetail messageDetail, 
                                         DtuFtpInfo deviceInfo, int transportTimes) {
        try {
            StringBuilder logContent = new StringBuilder();
            logContent.append("=== START POINT DETECTION ===\n");
            logContent.append("Timestamp: ").append(TIMESTAMP_FORMAT.format(new Date())).append("\n");
            logContent.append("Device ID: ").append(deviceId).append("\n");
            logContent.append("Record ID: ").append(messageDetail.getId()).append("\n");
            logContent.append("Time: ").append(messageDetail.getTime() != null ? TIMESTAMP_FORMAT.format(messageDetail.getTime()) : "null").append("\n");
            logContent.append("Speed: ").append(messageDetail.getSpeed()).append("\n");
            logContent.append("Vibration Status: ").append(messageDetail.getVibrationStatus()).append("\n");
            logContent.append("Radar Distance: ").append(messageDetail.getRadarDistance()).append("\n");
            logContent.append("Latitude: ").append(messageDetail.getLatitude()).append("\n");
            logContent.append("Longitude: ").append(messageDetail.getLongitude()).append("\n");
            logContent.append("\n");
            logContent.append("Device Configuration:\n");
            logContent.append("  tSpeed: ").append(deviceInfo.getTSpeed()).append("\n");
            logContent.append("  tTimeZone: ").append(deviceInfo.getTTimeZone()).append("\n");
            logContent.append("  tTimes: ").append(deviceInfo.getTTimes()).append("\n");
            logContent.append("  tEsMinDistance: ").append(deviceInfo.getTEsMinDistance()).append("\n");
            logContent.append("\n");
            logContent.append("Transport Times: ").append(transportTimes).append("\n");
            logContent.append("Message Sent: ").append(String.format("%03d", transportTimes + 1 + 900)).append("\n");
            logContent.append("================================\n\n");
            
            writeLog(deviceId, "start_point", logContent.toString());
        } catch (Exception e) {
            log.error("Error logging start point event for device {}", deviceId, e);
        }
    }
    
    /**
     * Log start point vibration data for detailed analysis
     * 
     * @param deviceId Device ID
     * @param context Transport context containing vibration records
     * @param deviceInfo Device configuration parameters
     */
    public static void logStartPointVibrationData(String deviceId, TransportContext context, DtuFtpInfo deviceInfo) {
        try {
            StringBuilder logContent = new StringBuilder();
            logContent.append("=== START POINT VIBRATION DATA ===\n");
            logContent.append("Timestamp: ").append(TIMESTAMP_FORMAT.format(new Date())).append("\n");
            logContent.append("Device ID: ").append(deviceId).append("\n");
            logContent.append("\n");
            
            logContent.append("Device Configuration:\n");
            logContent.append("  tSpeed: ").append(deviceInfo.getTSpeed()).append("\n");
            logContent.append("  tTimeZone: ").append(deviceInfo.getTTimeZone()).append(" seconds\n");
            logContent.append("  tTimes: ").append(deviceInfo.getTTimes()).append("\n");
            logContent.append("\n");
            
            logContent.append("Vibration Records in Time Window:\n");
            logContent.append("  Total Records: ").append(context.getVibrationRecords().size()).append("\n");
            
            // Get the current time
            Date now = new Date();
            long timeWindowMs = deviceInfo.getTTimeZone() * 1000L;
            
            // Use a Set to track unique timestamps to avoid counting duplicate timestamps multiple times
            Set<Long> uniqueTimestamps = new java.util.HashSet<>();
            
            // Count vibration records within the time window, deduplicating by timestamp
            for (VibrationRecord record : context.getVibrationRecords()) {
                if (record.getTimestamp() != null) {
                    long timeDiff = now.getTime() - record.getTimestamp().getTime();
                    if (timeDiff <= timeWindowMs && timeDiff >= 0) {
                        // Add timestamp to set (automatically handles deduplication)
                        uniqueTimestamps.add(record.getTimestamp().getTime());
                        
                        // Log individual record details
                        logContent.append("  Record - Time: ").append(TIMESTAMP_FORMAT.format(record.getTimestamp()))
                                .append(", Speed: ").append(record.getSpeed() != null ? record.getSpeed() : "null").append("\n");
                    }
                }
            }
            
            logContent.append("\n");
            logContent.append("Unique Vibration Count: ").append(uniqueTimestamps.size()).append("\n");
            logContent.append("Required Vibration Count (tTimes): ").append(deviceInfo.getTTimes()).append("\n");
            logContent.append("Vibration Condition Met: ").append(uniqueTimestamps.size() >= deviceInfo.getTTimes() ? "YES" : "NO").append("\n");
            logContent.append("===============================\n\n");
            
            // Write to the start directory as requested
            writeSpecificLog(deviceId, "start", logContent.toString());
        } catch (Exception e) {
            log.error("Error logging start point vibration data for device {}", deviceId, e);
        }
    }
    
    /**
     * Log end point detection event
     * 
     * @param deviceId Device ID
     * @param startPoint Start point of the transport
     * @param endPoint End point of the transport
     * @param transportDistance Calculated transport distance
     * @param transportTime Calculated transport time in seconds
     * @param transportTimes Transport times for the day
     * @param status Transport status (0=invalid, 1=valid)
     */
    public static void logEndPointEvent(String deviceId, TransportPoint startPoint, TransportPoint endPoint,
                                       double transportDistance, long transportTime, 
                                       int transportTimes, int status) {
        try {
            StringBuilder logContent = new StringBuilder();
            logContent.append("=== END POINT DETECTION ===\n");
            logContent.append("Timestamp: ").append(TIMESTAMP_FORMAT.format(new Date())).append("\n");
            logContent.append("Device ID: ").append(deviceId).append("\n");
            logContent.append("\n");
            logContent.append("Start Point:\n");
            logContent.append("  Record ID: ").append(startPoint.getRecordId()).append("\n");
            logContent.append("  Time: ").append(startPoint.getTimestamp() != null ? TIMESTAMP_FORMAT.format(startPoint.getTimestamp()) : "null").append("\n");
            logContent.append("  Latitude: ").append(startPoint.getLatitude()).append("\n");
            logContent.append("  Longitude: ").append(startPoint.getLongitude()).append("\n");
            logContent.append("  Speed: ").append(startPoint.getSpeed()).append("\n");
            logContent.append("  Radar Distance: ").append(startPoint.getRadarDistance()).append("\n");
            logContent.append("\n");
            logContent.append("End Point:\n");
            logContent.append("  Record ID: ").append(endPoint.getRecordId()).append("\n");
            logContent.append("  Time: ").append(endPoint.getTimestamp() != null ? TIMESTAMP_FORMAT.format(endPoint.getTimestamp()) : "null").append("\n");
            logContent.append("  Latitude: ").append(endPoint.getLatitude()).append("\n");
            logContent.append("  Longitude: ").append(endPoint.getLongitude()).append("\n");
            logContent.append("  Speed: ").append(endPoint.getSpeed()).append("\n");
            logContent.append("  Radar Distance: ").append(endPoint.getRadarDistance()).append("\n");
            logContent.append("\n");
            logContent.append("Transport Metrics:\n");
            logContent.append("  Distance: ").append(String.format("%.2f", transportDistance)).append(" meters\n");
            logContent.append("  Time: ").append(transportTime).append(" seconds\n");
            logContent.append("  Transport Times: ").append(transportTimes).append("\n");
            logContent.append("  Status: ").append(status == 1 ? "Valid" : "Invalid").append("\n");
            logContent.append("\n");
            logContent.append("Message Sent: ").append(String.format("%03d", transportTimes)).append("\n");
            logContent.append("============================\n\n");
            
            writeLog(deviceId, "end_point", logContent.toString());
        } catch (Exception e) {
            log.error("Error logging end point event for device {}", deviceId, e);
        }
    }
    
    /**
     * Log end point radar data for detailed analysis
     * 
     * @param deviceId Device ID
     * @param context Transport context containing radar records
     * @param deviceInfo Device configuration parameters
     */
    public static void logEndPointRadarData(String deviceId, TransportContext context, DtuFtpInfo deviceInfo) {
        try {
            StringBuilder logContent = new StringBuilder();
            logContent.append("=== END POINT RADAR DATA ===\n");
            logContent.append("Timestamp: ").append(TIMESTAMP_FORMAT.format(new Date())).append("\n");
            logContent.append("Device ID: ").append(deviceId).append("\n");
            logContent.append("\n");
            
            logContent.append("Device Configuration:\n");
            logContent.append("  tRadarDistance: ").append(deviceInfo.getTRadarDistance()).append(" mm\n");
            logContent.append("  tRadarTime: ").append(deviceInfo.getTRadarTime()).append(" seconds\n");
            logContent.append("\n");
            
            logContent.append("Radar Records in Time Window:\n");
            logContent.append("  Total Records: ").append(context.getRadarRecords().size()).append("\n");
            
            // Log all radar records
            for (RadarRecord record : context.getRadarRecords()) {
                if (record.getTimestamp() != null && record.getRadarDistance() != null) {
                    logContent.append("  Record - Time: ").append(TIMESTAMP_FORMAT.format(record.getTimestamp()))
                            .append(", Radar Distance: ").append(record.getRadarDistance()).append(" mm\n");
                }
            }
            
            logContent.append("\n");
            
            // Log radar condition evaluation
            if (deviceInfo.getTRadarDistance() != null && deviceInfo.getTRadarTime() != null) {
                double minRadarDistance = deviceInfo.getTRadarDistance().doubleValue();
                int radarTimeWindow = deviceInfo.getTRadarTime();
                
                logContent.append("Radar Condition Evaluation:\n");
                logContent.append("  Minimum Required Distance: ").append(minRadarDistance).append(" mm\n");
                logContent.append("  Required Time Window: ").append(radarTimeWindow).append(" seconds\n");
                
                // Check if radar condition is met
                boolean isRadarConditionMet = false;
                String specialCase = "";
                
                if (minRadarDistance == 0) {
                    specialCase = " (0 = infinity, always valid)";
                    isRadarConditionMet = true;
                } else if (minRadarDistance == 65535) {
                    specialCase = " (65535 = no signal, never valid)";
                    isRadarConditionMet = false;
                } else {
                    // Normal radar distance check
                    isRadarConditionMet = context.isRadarConditionMet(minRadarDistance, radarTimeWindow);
                }
                
                logContent.append("  Special Case: ").append(specialCase.isEmpty() ? "None" : specialCase).append("\n");
                logContent.append("  Radar Condition Met: ").append(isRadarConditionMet ? "YES" : "NO").append("\n");
            }
            
            logContent.append("=========================\n\n");
            
            // Write to the end directory as requested
            writeSpecificLog(deviceId, "end", logContent.toString());
        } catch (Exception e) {
            log.error("Error logging end point radar data for device {}", deviceId, e);
        }
    }
    
    /**
     * Log transport record creation event
     * 
     * @param deviceId Device ID
     * @param transportInfo Created transport record
     */
    public static void logTransportRecordEvent(String deviceId, DtuTransportInfo transportInfo) {
        try {
            StringBuilder logContent = new StringBuilder();
            logContent.append("=== TRANSPORT RECORD CREATED ===\n");
            logContent.append("Timestamp: ").append(TIMESTAMP_FORMAT.format(new Date())).append("\n");
            logContent.append("Device ID: ").append(deviceId).append("\n");
            logContent.append("Transport Record ID: ").append(transportInfo.getId()).append("\n");
            logContent.append("Start Time: ").append(transportInfo.getStartTime() != null ? TIMESTAMP_FORMAT.format(transportInfo.getStartTime()) : "null").append("\n");
            logContent.append("End Time: ").append(transportInfo.getEndTime() != null ? TIMESTAMP_FORMAT.format(transportInfo.getEndTime()) : "null").append("\n");
            logContent.append("Start Latitude: ").append(transportInfo.getStartLatitude()).append("\n");
            logContent.append("Start Longitude: ").append(transportInfo.getStartLongitude()).append("\n");
            logContent.append("End Latitude: ").append(transportInfo.getEndLatitude()).append("\n");
            logContent.append("End Longitude: ").append(transportInfo.getEndLongitude()).append("\n");
            logContent.append("Transport Distance: ").append(String.format("%.2f", transportInfo.getTransportDistance())).append(" meters\n");
            logContent.append("Transport Times: ").append(transportInfo.getTimes()).append("\n");
            logContent.append("Status: ").append(transportInfo.getStatus() == 1 ? "Valid" : "Invalid").append("\n");
            logContent.append("================================\n\n");
            
            writeLog(deviceId, "transport_record", logContent.toString());
        } catch (Exception e) {
            log.error("Error logging transport record event for device {}", deviceId, e);
        }
    }
    
    /**
     * Log device command sent event
     * 
     * @param deviceId Device ID
     * @param command Command sent to device (e.g., "901", "001")
     * @param description Description of the command
     */
    public static void logDeviceCommandEvent(String deviceId, String command, String description) {
        try {
            StringBuilder logContent = new StringBuilder();
            logContent.append("=== DEVICE COMMAND SENT ===\n");
            logContent.append("Timestamp: ").append(TIMESTAMP_FORMAT.format(new Date())).append("\n");
            logContent.append("Device ID: ").append(deviceId).append("\n");
            logContent.append("Command: ").append(command).append("\n");
            logContent.append("Description: ").append(description).append("\n");
            logContent.append("===========================\n\n");
            
            writeLog(deviceId, "device_command", logContent.toString());
        } catch (Exception e) {
            log.error("Error logging device command event for device {}", deviceId, e);
        }
    }
    
    /**
     * Log detailed distance calculation data for debugging and analysis
     * This includes all intermediate GPS points between start and end points
     * 
     * @param deviceId Device ID
     * @param startPoint Start point
     * @param endPoint End point
     * @param gpsPoints Intermediate GPS points
     */
    public static void logDistanceCalculationData(String deviceId, TransportPoint startPoint, 
                                                TransportPoint endPoint, java.util.Queue<TransportPoint> gpsPoints) {        try {
            // Check if start or end points have invalid coordinates (null or zero)
            if (isInvalidCoordinate(startPoint.getLatitude(), startPoint.getLongitude()) || 
                isInvalidCoordinate(endPoint.getLatitude(), endPoint.getLongitude())) {
                log.warn("Start or end point has invalid coordinates (null or zero), skipping distance calculation logging");
                return;
            }
            
            StringBuilder logContent = new StringBuilder();
            logContent.append("=== TRANSPORT DISTANCE CALCULATION DATA ===\n");
            logContent.append("Timestamp: ").append(TIMESTAMP_FORMAT.format(new Date())).append("\n");
            logContent.append("Device ID: ").append(deviceId).append("\n");
            logContent.append("\n");
            
            logContent.append("Start Point:\n");
            logContent.append("  Record ID: ").append(startPoint.getRecordId()).append("\n");
            logContent.append("  Time: ").append(startPoint.getTimestamp() != null ? TIMESTAMP_FORMAT.format(startPoint.getTimestamp()) : "null").append("\n");
            logContent.append("  Latitude: ").append(startPoint.getLatitude()).append("\n");
            logContent.append("  Longitude: ").append(startPoint.getLongitude()).append("\n");
            logContent.append("\n");
            
            logContent.append("Intermediate GPS Points:\n");
            if (gpsPoints != null && !gpsPoints.isEmpty()) {
                logContent.append("  Total Intermediate Points: ").append(gpsPoints.size()).append("\n");
                logContent.append("  Details:\n");
                
                TransportPoint previousPoint = startPoint;
                double totalDistance = 0.0;
                int pointIndex = 1;
                
                for (TransportPoint currentPoint : gpsPoints) {
                    // Skip invalid points (null or zero coordinates)
                    if (isInvalidCoordinate(currentPoint.getLatitude(), currentPoint.getLongitude())) {
                        logContent.append("    Point ").append(pointIndex).append(": INVALID (null or zero coordinates)\n");
                        pointIndex++;
                        continue;
                    }
                    
                    // Calculate distance from previous point
                    double segmentDistance = calculateHaversineDistance(
                        previousPoint.getLatitude(), previousPoint.getLongitude(),
                        currentPoint.getLatitude(), currentPoint.getLongitude());
                    
                    if (segmentDistance >= 0 && !Double.isNaN(segmentDistance)) {
                        totalDistance += segmentDistance;
                        logContent.append("    Point ").append(pointIndex).append(":\n");
                        logContent.append("      Record ID: ").append(currentPoint.getRecordId()).append("\n");
                        logContent.append("      Time: ").append(currentPoint.getTimestamp() != null ? TIMESTAMP_FORMAT.format(currentPoint.getTimestamp()) : "null").append("\n");
                        logContent.append("      Latitude: ").append(currentPoint.getLatitude()).append("\n");
                        logContent.append("      Longitude: ").append(currentPoint.getLongitude()).append("\n");
                        logContent.append("      Distance from previous point: ").append(String.format("%.2f", segmentDistance)).append(" meters\n");
                        logContent.append("      Cumulative distance: ").append(String.format("%.2f", totalDistance)).append(" meters\n");
                        previousPoint = currentPoint;
                    } else {
                        logContent.append("    Point ").append(pointIndex).append(": INVALID (distance calculation failed)\n");
                    }
                    pointIndex++;
                }
                
                // Calculate distance from last intermediate point to end point
                double finalSegmentDistance = calculateHaversineDistance(
                    previousPoint.getLatitude(), previousPoint.getLongitude(),
                    endPoint.getLatitude(), endPoint.getLongitude());
                
                if (finalSegmentDistance >= 0 && !Double.isNaN(finalSegmentDistance)) {
                    totalDistance += finalSegmentDistance;
                    logContent.append("    Final segment to end point:\n");
                    logContent.append("      Distance: ").append(String.format("%.2f", finalSegmentDistance)).append(" meters\n");
                    logContent.append("      Total transport distance: ").append(String.format("%.2f", totalDistance)).append(" meters\n");
                }
            } else {
                logContent.append("  No intermediate GPS points recorded\n");
                
                // Calculate direct distance from start to end point
                double directDistance = calculateHaversineDistance(
                    startPoint.getLatitude(), startPoint.getLongitude(),
                    endPoint.getLatitude(), endPoint.getLongitude());
                
                if (directDistance >= 0 && !Double.isNaN(directDistance)) {
                    logContent.append("  Direct distance from start to end point: ").append(String.format("%.2f", directDistance)).append(" meters\n");
                }
            }
            
            logContent.append("\n");
            logContent.append("End Point:\n");
            logContent.append("  Record ID: ").append(endPoint.getRecordId()).append("\n");
            logContent.append("  Time: ").append(endPoint.getTimestamp() != null ? TIMESTAMP_FORMAT.format(endPoint.getTimestamp()) : "null").append("\n");
            logContent.append("  Latitude: ").append(endPoint.getLatitude()).append("\n");
            logContent.append("  Longitude: ").append(endPoint.getLongitude()).append("\n");
            logContent.append("\n");
            
            logContent.append("==================================\n\n");
            
            // Write to the km directory as requested
            writeKmLog(deviceId, logContent.toString());
        } catch (Exception e) {
            log.error("Error logging distance calculation data for device {}", deviceId, e);
        }
    }
    
    /**
     * Check if coordinates are invalid (null or zero)
     * 
     * @param latitude  the latitude value
     * @param longitude the longitude value
     * @return true if coordinates are invalid, false otherwise
     */
    private static boolean isInvalidCoordinate(java.math.BigDecimal latitude, java.math.BigDecimal longitude) {
        return latitude == null || longitude == null || 
               java.math.BigDecimal.ZERO.compareTo(latitude) == 0 || java.math.BigDecimal.ZERO.compareTo(longitude) == 0;
    }
    
    /**
     * Calculate distance between two points using Haversine formula
     * 
     * @param lat1 Latitude of point 1
     * @param lon1 Longitude of point 1
     * @param lat2 Latitude of point 2
     * @param lon2 Longitude of point 2
     * @return Distance in meters
     */
    private static double calculateHaversineDistance(java.math.BigDecimal lat1, java.math.BigDecimal lon1, 
                                                   java.math.BigDecimal lat2, java.math.BigDecimal lon2) {
        // Check for null values
        if (lat1 == null || lon1 == null || lat2 == null || lon2 == null) {
            return 0.0;
        }
        
        // Check for zero coordinates
        if (java.math.BigDecimal.ZERO.compareTo(lat1) == 0 || java.math.BigDecimal.ZERO.compareTo(lon1) == 0 ||
            java.math.BigDecimal.ZERO.compareTo(lat2) == 0 || java.math.BigDecimal.ZERO.compareTo(lon2) == 0) {
            return 0.0;
        }
        
        // Convert BigDecimal to double for calculation
        double lat1Double = lat1.doubleValue();
        double lon1Double = lon1.doubleValue();
        double lat2Double = lat2.doubleValue();
        double lon2Double = lon2.doubleValue();
        
        final int EARTH_RADIUS = 6371; // Earth radius in kilometers
        
        // Convert latitude and longitude from degrees to radians
        double lat1Rad = Math.toRadians(lat1Double);
        double lon1Rad = Math.toRadians(lon1Double);
        double lat2Rad = Math.toRadians(lat2Double);
        double lon2Rad = Math.toRadians(lon2Double);
        
        // Haversine formula
        double deltaLat = lat2Rad - lat1Rad;
        double deltaLon = lon2Rad - lon1Rad;
        double a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
                   Math.cos(lat1Rad) * Math.cos(lat2Rad) *
                   Math.sin(deltaLon / 2) * Math.sin(deltaLon / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        
        // Distance in meters
        return EARTH_RADIUS * c * 1000;
    }
    
    /**
     * Write log content to file in the standard selog directory structure
     * 
     * @param deviceId Device ID
     * @param eventType Type of event (start_point, end_point, etc.)
     * @param content Log content to write
     */
    private static void writeLog(String deviceId, String eventType, String content) throws IOException {
        // Create directory structure: netty-log/selog/{device_id}/{yyyy-MM-dd}/
        String dateStr = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        Path logDir = Paths.get(LOG_BASE_DIR, deviceId, dateStr);
        Files.createDirectories(logDir);
        
        // Create log file with timestamp
        String fileName = eventType + "_" + FILENAME_FORMAT.format(new Date()) + ".txt";
        Path logFile = logDir.resolve(fileName);
        
        // Write content to file
        try (FileWriter writer = new FileWriter(logFile.toFile(), true)) {
            writer.write(content);
        }
    }
    
    /**
     * Write log content to specific directory (start or end) as requested
     * 
     * @param deviceId Device ID
     * @param logType Type of log (start or end)
     * @param content Log content to write
     */
    private static void writeSpecificLog(String deviceId, String logType, String content) throws IOException {
        // Create directory structure: netty-log/selog/{logType}/{device_id}/{yyyy-MM-dd}/
        String dateStr = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        Path logDir = Paths.get("netty-log", "selog", logType, deviceId, dateStr);
        Files.createDirectories(logDir);
        
        // Create log file with timestamp
        String fileName = logType + "_data_" + FILENAME_FORMAT.format(new Date()) + ".txt";
        Path logFile = logDir.resolve(fileName);
        
        // Write content to file
        try (FileWriter writer = new FileWriter(logFile.toFile(), true)) {
            writer.write(content);
        }
    }
    
    /**
     * Write log content to km directory as requested
     * 
     * @param deviceId Device ID
     * @param content Log content to write
     */
    private static void writeKmLog(String deviceId, String content) throws IOException {
        // Create directory structure: netty-log/selog/km/{device_id}/{yyyy-MM-dd}/
        String dateStr = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        Path logDir = Paths.get("netty-log", "selog", "km", deviceId, dateStr);
        Files.createDirectories(logDir);
        
        // Create log file with timestamp
        String fileName = "distance_data_" + FILENAME_FORMAT.format(new Date()) + ".txt";
        Path logFile = logDir.resolve(fileName);
        
        // Write content to file
        try (FileWriter writer = new FileWriter(logFile.toFile(), true)) {
            writer.write(content);
        }
    }
}